package coreconcurrency.call;

import coreconcurrency.MockDto;
import coreconcurrency.MockService;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;

/**
 * create by yongli on 2022-03-03 20:38
 * 尽量使用函数式编程，使用函数式接口，避免一个小任务都要创建对象
 * 这是一个批量地，并发地,异步的删除数据库的函数
 *
 * 基本上就是不用我自己启动线程了，全部交给ExecuteService对象，我创建了对象，然后submit一下就可以了。
 *  自己多尝试一下独立思考。已有的类和要实现的功能，就是思考的材料，想想该怎么做。
 *  Future<T> submit(Callable<T>):提交一个Callable对象，获得一个Callble对象，
 *  只不过这个Callable对象会返回我们想要的结果。
 *
 *  异步回调模式
 */

public class ExecutorTask {

    private static final int MAX = 76363990;
    // 删掉同步库存日志
    private static final String URL = "/api/passive-sap/accessoryLibrary/saveOrUpdate";
    private static final String MES = "MES";
    private static final int SIZE = 3000;

    private static final int CORE = 1;
    // 查看newFixedThreadPool的源码

    static ExecutorService excutor = Executors.newFixedThreadPool(CORE);

    // 这个pool有很多参数
    static ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3,
            60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));

    static MockService mockService = new MockService();

    public void deleteLastLog() {
        int count = 20;
        while (count * SIZE < MAX) {
            List<FutureTask<Integer>> futureTasks = new ArrayList<FutureTask<Integer>>();
            for (int i = 0; i < 3 * CORE; i++) {
                int num = count + i;
                FutureTask<Integer> futureTask = new FutureTask<Integer>(() -> deleteLastLogOne(num));
                excutor.submit(futureTask);
                futureTasks.add(futureTask);
            }

            while (futureTasks.size() > 0) {
                Iterator<FutureTask<Integer>> iterator = futureTasks.iterator();
                // 多重循环
                for (; iterator.hasNext(); ) {
                    FutureTask<Integer> task = iterator.next();
                    if (task.isDone()) {
                        iterator.remove();
                        try {
//                            System.out.println(task.get());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            count += 3 * CORE;
        }
        System.out.println(count * SIZE);
    }

    public Integer deleteLastLogOne(int count) {

        List<MockDto> ls = mockService.list(new Object());

        List<Integer> res = new ArrayList<>();
        for (MockDto dto : ls) {
            if (URL.equals(dto.getName())) {
                res.add(dto.getId());
            }
        }
//        System.out.println(res.size());
        if (res.size() > 0) {
            System.out.println(res.size());
            mockService.delete(res);
        }
        return res.size();
    }
}
